热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

色调|白色_.NET深度指南:Colors

篇首语:本文由编程笔记#小编为大家整理,主要介绍了.NET深度指南:Colors相关的知识,希望对你有一定的参考价值。作者|PeterHuber

篇首语:本文由编程笔记#小编为大家整理,主要介绍了.NET 深度指南:Colors相关的知识,希望对你有一定的参考价值。


作者 | Peter Huber


译者 | 王强


策划 | 丁晓昀


我不知道你们是什么情况,但我自己在过去多年中都因为.NET 色彩(Colors)类中可用的色彩数量有限而头痛不已,为此我试图用 ColorPickers 获得匹配的色彩并努力去理解各种色彩模型。为了让我的生活轻松一些,我写了几个小方法可以把任何色彩改成黑白的,还有一个方法可以混合色彩。有了这些方法后,我得到了匹配度很高的色彩,有点像 GradientBrush 中的渐变效果。


然后我给自己找了个麻烦,就是写这篇文章来帮助其他人使用我的方法。为了解释这些方法的原理,我别无选择,只能详细调查背后到底发生了什么。所以这篇文章主要是关于色彩、色彩模型、色调、亮度之类的东西,但解释它们时用的是让软件开发者不需要数学或物理专业背景就能理解的简单术语。


如果你已经对色彩有了扎实的了解,你可以直接跳到“精确生成你自己的色彩”这一章,那里有实际的代码。


色彩空间 HSB:色调、饱和度和亮度


我们可能都知道,电脑屏幕上的色彩是由像素生成的,每个像素由 3 个点组成,分别发出红、绿、蓝三色光,所以它们被叫做 R、G、B 像素点。然而,这里已经有了第一个误解,因为在实际情况下 G 不是 Colors.Green,而是 Colors.Lime(黄绿)。人眼对色彩有三种不同的感受器,所以人们选择了 R、G 和 B 的色彩(色调)来与这些感受器很好地匹配起来,这里匹配的是黄绿而不是“正常”的绿色。有了 RGB 像素,显示器可以生成人眼可以感受到的大多数色彩——当然只是大多数。与太阳等光源相比,这些色彩的“强度”(亮度)相当有限。



每种色彩都是由 3 个点各自发出的光的多少来定义的。一个点的数值可以介于 0(不发光)和 255(或十六进制的 0xFF)之间,255 意味着全强度发光。为了看到其中一种原色,例如红色,R 要被设置为 255,G 和 B 被设置为 0,这样就可以得到最亮的红色。如果我们想要一个暗一些的红色,只需降低 R 的值即可。一旦 R 为 0,得到的色彩就是黑色的,因为没有任何点发射出任何光线。这是一个改变色彩亮度的例子,而亮度是每一种色彩都有的三个属性之一。有趣的是,亮度的定义不是从 0 到 255,而是从 0 到 1 或 0 到 100%。


色彩的另一个属性被称为色调。色调为黄色、橙色、红色等色彩分配了不同的数字。当 3 个点中的一个是 255,一个是 0,而“中间”(第三个)为任何数值时,我们可以生成最纯粹的色调。例如,R 225, G 255, B 0 结合了红色和绿色,其结果是?奇怪的是,其结果是黄色!原因是,当两盏灯照在同一个地方时,这个地方会变亮而不是变暗。如果我们把 R、G 和 B 混合在一起,都以最大亮度发光,我们就会得到白色的光。这与绘画的色彩正好相反。如果我们把许多绘画的色彩混合在一起,就会得到一些深灰色的东西,很难看。



R:FF G:FF B:00 = 黄色


R:00 G:FF B:FF = 青色


R:FF G:00 B:FF = 品红


顺便说一下,这些是显示器可以生成的最亮的色彩,因为它们使用了 2 个全亮的点,而红、绿、蓝色只使用了 1 个点。对于其他所有色调,亮度第二强的点发出的亮度低于 255。正是这个既不是 255 也不是 0 的“中间”点定义了色调。将这个中间点的亮度从 0 缓慢递增到 255,我们可以得到比如说在红色(FF0000)和黄色(FFF00)之间的所有色调。总共有 6 种这样的转换:


  • 255 红色和一些绿色:红到黄

  • 255 红色和一些蓝色:红到紫

  • 255 绿色和一些红色:绿到黄

  • 255 绿色和一些蓝色:绿到蓝绿

  • 255 蓝色和一些绿色:蓝到蓝绿

  • 255 蓝色和一些红色:蓝到紫


当我们逐渐改变 R、G 或 B 时,会得到类似彩虹的东西。



左边和右边边界的色彩是红色。由于这个原因,彩虹常常被画成一个圆形。色调是以度数来定义的,红色为 0 和 360 度。


第三个色彩属性被称为饱和度。到目前为止,我们只处理了完全饱和的色彩,即最暗的点亮度是 0。如果我们想让一个完全饱和的色彩更亮,使其最终接近白色,我们需要降低饱和度,按比例增加所有三个点的亮度,使其接近 255。要把饱和度从 100% 降低到 50%,我们必须把现在的值与 255 之间的差值减半。举例:


现值:R 255, G 128, B 0

将饱和度从 1 降低到 0.5


新的 R 值 = 255 + 0.5 * (255-255) = 255

新的 G 值 = 128 + 0.5 * (255-128) = 192(或 191,取决于四舍五入的情况)

新的 B 值 = 0 + 0.5 * (255-0) = 128(或 127,取决于四舍五入的情况)

将饱和度从 1 降低到 0(= 白色)。


新的 R 值 = 255 + 1 * (255-255) = 255

新的 G 值 = 128 + 1 * (255-128) = 255

新的 B 值 = 0 + 1 * (255-0) = 255

红色从 100% 的饱和度降到 0%:


现在我们可以再画一次彩虹,加入一些饱和度和亮度的变化。X 轴增加了从 0 到 360 的色调。在中间的是以 100% 的饱和度和 100% 的亮度显示的每个色调。在上半部分,亮度保持在 100%,饱和度降低到 0%,这就形成了白色。在下半部分,饱和度保持 100%,亮度减少到 0%,这就形成了黑色。



注意黄色、青色和品红在变成白色或黑色之前比其他色调能保持更长时间。它们是最强的色彩,因为有 2 个点在全亮度闪耀。


一个接近 0% 饱和度和 100% 亮度的色调看起来是白色的。白色的值是 FFFFF,色调和饱和度是未定义的。


一个饱和度为 100%、亮度接近 0% 的色调看起来是黑色的。黑色的值是 0000,色调和饱和度都没有定义。


一个所有 3 个点都以相同强度发光的色彩看起来是灰色的。一个可能的值是 808080。



注意:对于灰色(即 R、G 和 B 有相同的值),色调和饱和度都没有定义,只有亮度有意义的值。我们也可以说,黑色、灰色和白色都不是色彩。黑色 0000 的亮度为 0,白色 FFFFF 的亮度为 1。仅靠亮度来控制白色、灰色和黑色的外观有一个奇怪的后果,我们可以在下一张图中看到。


我们现在已经涵盖了显示器可以显示的所有色彩了吗?实际上,我们只展示了所有可能的 R、G 和 B 组合中的不到 1%,也就是说,只有那些一个点是 255(100% 亮度)或一个点是 0(100% 饱和度)的组合。比方说,我们首先将 FF8000(一种橙红色)的饱和度改为 50%,得到 FFC080。当我们再把亮度改为 50% 时,得到 806040。现在的色调仍然是橙红色,但色彩更接近于深灰色。


下面是一张包含所有可能的饱和度和亮度组合的红色图片。



我想这是本文中最令人困惑的图片。基本上,我想把 Y 轴(从上到下)上的色彩从红色变成黑色,意味着亮度从 1 到 0,而 X 轴(从左到右)上的色彩从红色变成白色,意味着饱和度从 1 到 0,我本来以为白色和黑色也会混合,右下角会变成灰色,但情况并非如此。只要 R、G、B 有相同的值,色调和饱和度就失去了意义。只有亮度对白色、灰色和黑色(右边界)的色彩有影响。更糟糕的是整个下边界只有黑色,因为一旦亮度为 0,色调和饱和度又变得毫无意义了。


如果你也感到困惑,我们就是一伙儿的了。但这就是 HSB 色彩方案的工作方式。当你只操作 RGB 值时,很难说出结果会是什么样子(还记得 R 和 G 混合的结果是黄色吗?)。在 HSB 色彩空间中操作色彩时,只要你只改变饱和度和亮度,黄色就一直是黄色,直到亮度变成 1(白色)或 0(黑色),这时色调和饱和度就会消失。


HSL 色彩空间


还有一个色彩空间叫做 HSL——色调(Hue)、饱和度(Saturation)和亮度(Luminosity)。它的色调与 HSB 相同,但饱和度不朝向白色,而是朝向灰色;光亮度则从 0= 黑色,0.5= 灰色到 1= 白色。HSL 在从黑白电视到彩色电视的过渡过程中非常有用。黑白电视只显示 L 值,而彩色电视则使用 HSL。


取色器


在过去,我总是很难理解取色器是如何工作的,不知道为什么它们有时会失败。现在了解了色调、饱和度和亮度,以及它们与 RGB 色彩的关系后,取色器也就更容易理解了。


PowerPoint 2010 取色器



PowerPoint 使用 HSL 色彩空间。在色彩选择区,它们水平显示所有的色调,垂直显示饱和度。在 HSL 色彩空间中,饱和度为 0 是灰色的,因此完整的下边界是灰色的。右边是一个滚动条,可以改变亮度,0 表示黑色,128 表示灰色,255 表示白色(它不使用 0-100%,而是 0-255)。在 0 和 255 时,色调和饱和度失去了意义。最纯粹的色彩是在亮度 128。


例如,在 HSL 中选择一个蓝色,然后将亮度降低到 0,并切换到 RGB 显示,正确显示为 0,0,0。把 R 增加一点,然后再设置为 0,再切换回 HSV,现在显示的是色调和饱和度为 0,当然,这应该是未定义的。色调为 0 意味着红色,但黑色没有色调。色彩区域的指针仍然显示最初选择的蓝色,而不是色调为 0 的红色。这不仅让我感到困惑,而且当我不断地鼓捣黑色、灰色和白色,并在 RGB 和 HSL 视图之间切换时,我的 PowerPoint 终于崩溃了。


Paint.net 4.2 取色器



事实证明,paint.net 的取色器用起来更容易。他们使用的是 HSV 色彩模型,这与 HSB 色彩模型相同,他们只是把亮度这个词改为体积(volume)。我很欣赏的一点是他们在同一个窗口中显示 RGB 值和 HSV 值,这使我更容易理解改变一个 HSV 值是如何影响 RGB 值的。它在色彩圈的边界上显示所有可用的色调,中间是白色,意味着 0% 的饱和度。要使色彩变深,必须改变体积(亮度)参数的滑块。当然,它的黑色、灰色和白色的色调也为零,但至少在我鼓捣这些数值时它没有崩溃。


WinUI 取色器


可悲的事实是,WPF 没有取色器。这很像微软多年前放弃了 WPF,试图强迫我们改为写 UWP 应用程序的情况。许多开发者会说“不,谢谢你”,并留在了 WPF。所以现在微软正在引入 XAML,允许 WPF 项目使用“较新”的控件,取色器就是一个例子——可这些控件从一开始就应该包含在 WPF 中才对。我还没有在项目中用过 WinUI 取色器,但我在 XAML 控件库中运行它是这样的:



它的工作原理有点像 PowerPoint 中的取色器,但使用 HSV(HSB)代替,这意味着色彩区域的下部是白色的,而不是灰色的。下方的滚动条改变 V 值(亮度)。当设置为黑色时,色调和饱和度保持其最新值,即使后来在色彩区域选择了不同的色彩也一样。当值(亮度)增加时,色彩区的圆圈就会跳回原来的色调。这样很奇怪,但至少没有崩溃。


Web 取色器


下面是一个基于互联网的取色器的例子,在 html 5 的 input 标签中定义:



HTML 只定义了 input 标签的功能,取色器的实际外观取决于浏览器。下面是 Chrome 浏览器的截图。



它使用一个彩虹滚动条来选择色调。上面的矩形在所有可能的饱和度和亮度组合中显示该色调。关于如何计算数值的详细解释,请看前面关于 HSB 的解释,它的情况几乎是一样的,只是白角和红角换了位置。得到的值可以显示为 RGB(整数或十六进制)和 HSL。


.NET 的色彩类


色彩(Colors)类提供了一些标准色彩。它们是由委员会将一些不同的色彩方案混合起来选择出来的,有时结果很奇怪。例如,Colors.Gray 比 Colors.DarkGray 要深一些。很奇怪,对吗?



或者 2 个不同的名字代表的其实是同一种色彩,比如 Aqua(00FFFF)和 Cyan(00FFFF)或者 Fuchsia(FF00FF)和 Magenta(FF00FF)。不幸的是,Colors 帮助页面是按字母顺序显示色彩的,如果你知道名字就很容易找到它们,但要分辨出哪些色彩彼此相近或相配却非常困难。



所以我花了一些时间,按色调垂直排序,然后按亮度和饱和度水平排序。这里的结果列出了与 Colors 帮助页面中完全相同的色彩:



精确生成定制色彩


让色彩变亮或变暗(降低饱和度和 / 或亮度)


当我设计一个新的应用程序并决定要使用的色彩方案时,我通常不能使用色彩类提供的调色板。通常情况下,我需要带有阴影的相同色调(不同的饱和度和亮度)。要做到这一点只需几行代码就能搞定了。下面是降低任何色彩的饱和度(使之更亮)或降低亮度(使之更暗)的方法。


///


/// Makes the color lighter if factor>0 and darker if factor<0. 1 returns white, -1 returns
/// black.
///

public static Color GetBrighterOrDarker(this Color color, double factor)
if (factor<-1) throw new Exception($"Factor factor must be greater equal -1.");
if (factor>1) throw new Exception($"Factor factor must be smaller equal 1.");
if (factor&#61;&#61;0) return color;
if (factor<0)
//make color darker, changer brightness
factor &#43;&#61; 1;
return Color.FromArgb(
color.A,
(byte)(color.R*factor),
(byte)(color.G*factor),
(byte)(color.B*factor));
else
//make color lighter, change saturation
return Color.FromArgb(
color.A,
(byte)(color.R &#43; (255-color.R)*factor),
(byte)(color.G &#43; (255-color.G)*factor),
(byte)(color.B &#43; (255-color.B)*factor));


令人惊讶的是只用几行代码就可以改变饱和度和亮度。有点困难的是如何正确计算饱和度&#xff0c;而这个方法就很方便。


红、绿、蓝&#xff0c;系数为 -1 到 1&#xff1a;



为了得到更亮的色彩&#xff0c;不要使用绿色&#xff0c;因为绿色不是 100% 的饱和度——而要使用黄色、品红和青色。



请注意&#xff0c;先应用 0.5 的系数&#xff0c;然后再应用 -0.5 的系数是不会得到原来色彩的。第一次调用改变的是饱和度&#xff0c;第二次调用改变的是亮度。


我喜欢使用这种方法的原因是&#xff1a;


  1. 我可以用小幅度而可控的步骤增加、减少变化&#xff0c;并在 GUI 中看到结果。

  2. 我可以很容易地创建阴影和高光&#xff0c;它们应该有相同的色调&#xff0c;但饱和度和亮度则不同。


混合色调


通常情况下&#xff0c;一个用户界面不应该使用太多的色调&#xff0c;有几个色调并从中混合一些色调可能就够了。下面两种方法可以达到这个目的&#xff0c;第一种是将两种色彩一半一半地混合&#xff0c;第二种是让一种色彩多于另一种色彩。


///


/// Mixes 2 colors equally
///

public static Color Mix(this Color color1, Color color2)
return Mix(color1, 0.5, color2);
///
/// Mixes factor*color1 with (1-factor)*color2.
///

public static Color Mix(this Color color1, double factor, Color color2)
if (factor<0) throw new Exception($"Factor factor must be greater equal 0.");
if (factor>1) throw new Exception($"Factor factor must be smaller equal 1.");
if (factor&#61;&#61;0) return color2;
if (factor&#61;&#61;1) return color1;
var factor1 &#61; 1 - factor;
return Color.FromArgb(
(byte)((color1.A * factor &#43; color2.A * factor1)),
(byte)((color1.R * factor &#43; color2.R * factor1)),
(byte)((color1.G * factor &#43; color2.G * factor1)),
(byte)((color1.B * factor &#43; color2.B * factor1)));

这就是生成良好匹配的色彩所需要的一切操作。第一张图片显示了每种“主”色如何与其他“主”色进行不同程度的混合&#xff0c;同样是红、绿和蓝&#xff1a;



然而&#xff0c;如果你用黄色、品色和青色来代替可能会更好。



在这里&#xff0c;我真的觉得这些色彩比混合红、绿、蓝更漂亮。当然&#xff0c;它们可能太纯粹了。GUI 经常使用灰暗的色调&#xff0c;使用 GetBrighterOrDarker() 可以很容易地在混合后做出灰暗的色调。


获取 RGB 色彩的色调、饱和度和亮度


我还做了一些写这篇文章时所需要的方法&#xff0c;可能也很有用。第一个方法是计算一个 RGB 色彩的色调、饱和度和亮度。


///


/// Returns the hue, saturation and brightness of color
///

public static (int Hue, double Saturation, double Brightness)GetHSB(this Color color)
int max &#61; Math.Max(color.R, Math.Max(color.G, color.B));
int min &#61; Math.Min(color.R, Math.Min(color.G, color.B));
int hue &#61; 0;//for black, gray or white, hue could be actually any number, but usually 0 is
//assign, which means red
if (max-min!&#61;0)
//not black, gray or white
int maxMinDif &#61; max-min;
if (max&#61;&#61;color.R)
#pragma warning disable IDE0045 // Convert to conditional expression
if (color.G>&#61;color.B)
#pragma warning restore IDE0045
hue &#61; 60 * (color.G-color.B)/maxMinDif;
else
hue &#61; 60 * (color.G-color.B)/maxMinDif &#43; 360;

else if (max&#61;&#61;color.G)
hue &#61; 60 * (color.B-color.R)/maxMinDif &#43; 120;
else if(max &#61;&#61; color.B)
hue &#61; 60 * (color.R-color.G)/maxMinDif &#43; 240;


double saturation &#61; (max &#61;&#61; 0) ? 0.0 : (1.0-((double)min/(double)max));
return (hue, saturation, (double)max/0xFF);

我从“CodeProject&#xff1a;在.NET 中操纵色彩第 1 部分”中复制了这段代码&#xff08;其实它赢得了“2007 年 5 月最佳 C# 文章”&#xff09;&#xff0c;并对其做了点微小的“改进”。例如&#xff0c;我觉得整数 0 到 360 足以列举所有的色调。原代码使用浮点数&#xff0c;所以你可以有无限多的色调。这可能会让计算不那么容易受到四舍五入错误的影响&#xff0c;但我想人们看不出这有什么不同。


将任何色彩的饱和度和亮度提高到 100%


在我选择匹配色彩的方法中&#xff0c;最好从饱和度和亮度为 100% 的"纯色"开始&#xff0c;然后再进行混合&#xff0c;使其变得更深或更亮。下面的方法接收任何 RGB 色彩&#xff0c;并返回一个具有相同色调的 RGB 色彩&#xff0c;但饱和度和亮度为 100%。


///


/// Returns a color with the same hue, but brightness and saturation increased to 100%.
///

public static Color ToFullColor(this Color color)
//step 1: increase brightness to 100%
var max &#61; Math.Max(color.R, Math.Max(color.G, color.B));
var min &#61; Math.Min(color.R, Math.Min(color.G, color.B));
if (max&#61;&#61;min)
//for black, gray or white return white
return Color.FromArgb(color.A, 0xFF, 0xFF, 0xFF);

double rBright &#61; (double)color.R * 255 / max;
double gBright &#61; (double)color.G * 255 / max;
double bBright &#61; (double)color.B * 255 / max;
//step2: increase saturation to 100%
//lower smallest R, G, B component to zero and adjust second smallest color accordingly
//p &#61; (smallest R, G, B component) / 255
//(255-FullColor.SecondComponent) * p &#43; FullColor.SecondComponent &#61; color.SecondComponent
//FullColor.SecondComponent &#61; (color.SecondComponent-255p)/(1-p)
if (color.R&#61;&#61;max)
if (color.G&#61;&#61;min)
double p &#61; gBright / 255;
return Color.FromArgb(color.A, 0xFF, 0, (byte)((bBright-gBright)/(1-p)));
else
double p &#61; bBright / 255;
return Color.FromArgb(color.A, 0xFF, (byte)((gBright-bBright)/(1-p)), 0);

else if (color.G&#61;&#61;max)
if (color.R&#61;&#61;min)
double p &#61; rBright / 255;
return Color.FromArgb(color.A, 0, 0xFF, (byte)((bBright-rBright)/(1-p)));
else
double p &#61; bBright / 255;
return Color.FromArgb(color.A, (byte)((rBright-bBright)/(1-p)), 0xFF, 0);

else
if (color.R&#61;&#61;min)
double p &#61; rBright / 255;
return Color.FromArgb(color.A, 0, (byte)((gBright-rBright)/(1-p)), 0xFF);
else
double p &#61; bBright / 255;
return Color.FromArgb(color.A, (byte)((rBright-bBright)/(1-p)), 0, 0xFF);



这个方法是我自己写的。这里的数学要求比较高&#xff0c;我希望我的计算是正确的。你可以使用任何取色器来轻松验证它。如果你发现任何不一致的地方&#xff0c;请告诉我。


作者简介&#xff1a;


Peter Huber 是 50 年前在 HP35 上开始学习编程的。然后他从 PL1、Assembler、Pascal、Modula、Java 转到 C#&#xff0c;并且喜欢上 C# 语言已经有 15 年了。他已经在新加坡退休&#xff0c;他的大部分时间都花在编写单用户 WPF 应用程序上。


原文链接&#xff1a;


https://www.infoq.com/articles/colors-dotnet-guide/


推荐阅读
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • IT方面的论坛太多了,有综合,有专业,有行业,在各个论坛里混了几年,体会颇深,以前是论坛哪里人多 ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • ***byte(字节)根据长度转成kb(千字节)和mb(兆字节)**parambytes*return*publicstaticStringbytes2kb(longbytes){ ... [详细]
author-avatar
Money00Fish
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有